#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <time.h>

#include "public.h"
#include "debug.h"

/*
 * abstruct : main program.
 */

int main(int argc, char ** argv)
{
	int com;
	pthread_t com_read_id;
	pthread_t dis_time_id;
	void * ptr;
	pthread_attr_t attr;

	system("himm 0x12040088 0x1");
	system("himm 0x1204008C 0x1");
	system("himm 0x12040090 0x1");
	system("himm 0x12040094 0x1");

	if (argc != 2) {
		printf("usage: %s 0|1|2|3.\n", argv[0]);
		exit(0);
	}
	
	trigger_open();

	com = atoi(argv[1]);
	uart_init(com, 115200, 8, 1, 'n');

	pthread_attr_init(&attr);

	com_read_id = 0;
	pthread_create(&com_read_id, &attr, uart_receive_thread, NULL);

	dis_time_id = 0;
	pthread_create(&dis_time_id, &attr, display_system_time, NULL);

	pthread_join(com_read_id, & ptr);
	pthread_join(dis_time_id, & ptr);

	return 0;
}

#ifdef VERIFICATION
int display_gps_time(long tv_sec)
{
	struct tm * tm;

	tm = gmtime(&tv_sec);
	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "gps time : %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);

	#ifdef DEBUG
	tm = localtime(&tv_sec);
	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "%02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
	#endif

	return 0;
}

static unsigned long long  spts_temp = 0;
static unsigned long long  gpts_temp = 0;

int display_gps_microsecond(long tv_sec, long tv_usec)
{
	gpts_temp = (unsigned long long)tv_sec * 1000000 + (unsigned long long)tv_usec;
	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "gps microsecond : %lld\n", gpts_temp);

	get_system_time_microsecond();
	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "Range of error = %lld\n", spts_temp - gpts_temp);

	spts_temp = 0;
	gpts_temp = 0;

	return 0;
}

int get_system_time_second(void)
{
	time_t timep;
	struct tm * p;

	time(&timep);
	p = localtime(&timep);

	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "sys time : %02d:%02d:%02d\n", p->tm_hour, p->tm_min, p->tm_sec);

	return 0;
}

int get_system_time_microsecond(void)
{
	struct timespec tp;

	clock_gettime(CLOCK_REALTIME,&tp);

	spts_temp = tp.tv_sec;
	spts_temp = spts_temp * 1000000 + tp.tv_nsec / 1000;
	trace_dbg(DEBUG_MSG_LEVEL_DEBUG, "sys microsecond : %lld\n", spts_temp);
	fflush(stdout);

	return 0;
}

void * display_system_time(void * param)
{
	while (1) {
		trigger_jump();	/* duo chu [mov    $0x0,%eax] */
		#ifdef DEBUG
		get_system_time_second();
		get_system_time_microsecond();		
			
		sleep(1);
		msleep(100);
		#endif
	}
}
#endif


